package com.platform.demo;

import com.platform.demo.PlatformContext.JobWrapper;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
import java.util.jar.JarFile;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.PropertiesPropertySource;

@SpringBootApplication
public class DemoApplication {

  public static void main(String[] args) throws MalformedURLException {
    ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
//
    var cuurentClassLoader = Thread.currentThread().getContextClassLoader();

    String jarPath = "C:\\Project\\platform-demo\\job\\target\\job-0.0.1-SNAPSHOT-jar-with-dependencies.jar";
//    String jarPath = "C:\\Project\\platform-demo\\job\\target\\job-0.0.1-SNAPSHOT.jar";
    String jobId = "1";

    File file = new File(jarPath);

    var classLoader = new PlatformClassLoader(new URL[]{file.toURI().toURL()}, Thread.currentThread().getContextClassLoader());


    CompletableFuture.runAsync(() -> {
      try {
        Thread.currentThread().setContextClassLoader(classLoader);

        String startClass = "com.platform.job.BootStrap";
        Class c = classLoader.loadClass(startClass);
        SpringApplication childApplication = new SpringApplication(c);

        JarFile jarFile = new JarFile(file);

        childApplication.addInitializers(applicationContext -> {
          try {
            Properties properties = new Properties();
            properties.load(jarFile.getInputStream(jarFile.getEntry("application.properties")));

            var ps = new PropertiesPropertySource("properties", properties);
            applicationContext.getEnvironment().getPropertySources().addFirst(ps);
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
        });
        var childCtx = childApplication.run();
        childCtx.setParent(context);
        JobWrapper jobWrapper = new JobWrapper(jobId, null, "com.platform.job.JobTest", classLoader, childCtx);
        PlatformContext.add(jobId, jobWrapper);
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      } catch (IOException e) {
        throw new RuntimeException(e);
      } finally {
        Thread.currentThread().setContextClassLoader(cuurentClassLoader);
      }

    }).join();

  }
}
